using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace EuropeEngulfed.NET
{
    partial class AssignCombatLossesDialog : Form
    {
        private class BlockInfo
        {
            public Block block;
            public int numLosses;
            public BlockInfo(Block blockToCopy)
            {
                numLosses = 0;
                this.block = blockToCopy.Copy();
            }
        };

        private bool shownForAttacker;
        List<BlockInfo> activeArmorBlockList;
        List<BlockInfo> activeInfantryBlockList;
        List<Block> nonActiveArmorBlockList;
        List<Block> nonActiveInfantryBlockList;
        private List<GroundSupportUnit> defenderGSUList;
        private List<GroundSupportUnit> attackerGSUList;
        private int numInfantryHits;
        private int numArmorHits;

        public AssignCombatLossesDialog(IGameStateInfoProvider gameInfoProvider, MapInfo.RegionID battleRegion, bool shownForAttacker, GameController.playerType attacker, bool assault, Dictionary<MapInfo.CountryID, int> attackingGSUSelections, Dictionary<MapInfo.CountryID, int> defendingGSUSelections, int numInfantryHits, int numArmorHits, List<MapInfo.CountryID> countriesSpendingSAInBattle)
        {
            InitializeComponent();
            if (assault)
                this.Text = "Assault battle in " + Enum.GetName(battleRegion.GetType(), battleRegion) + "  - Assign Losses";
            else
                this.Text = "Battle in " + Enum.GetName(battleRegion.GetType(), battleRegion) + "  - Assign Losses";

            this.shownForAttacker = shownForAttacker;
            this.numInfantryHits = numInfantryHits;
            this.numArmorHits = numArmorHits;
            activeArmorBlockList = new List<BlockInfo>();
            activeInfantryBlockList = new List<BlockInfo>();
            nonActiveArmorBlockList = new List<Block>();
            nonActiveInfantryBlockList = new List<Block>();
            defenderGSUList = new List<GroundSupportUnit>();
            attackerGSUList = new List<GroundSupportUnit>();
            if (shownForAttacker)
            {
                if (attacker == GameController.playerType.AlliedPlayer)
                {
                    foreach (Block block in gameInfoProvider.GetRegionsAlliedBlockList(battleRegion))
                    {
                        BlockInfo blockInfo = new BlockInfo(block);
                        bool addBlock = false;
                        if (countriesSpendingSAInBattle != null && countriesSpendingSAInBattle.Count > 0)
                        {
                            if (countriesSpendingSAInBattle.Contains(block.CountryOwner) || (countriesSpendingSAInBattle.Contains(MapInfo.CountryID.USA) && block.CountryOwner == MapInfo.CountryID.FreeFrance) || (MapInfo.IsAxisMinorPower(block.CountryOwner) && countriesSpendingSAInBattle.Contains(MapInfo.CountryID.Germany)))
                                addBlock = true;
                        }
                        else
                            addBlock = true;
                        if (addBlock)
                        {
                            if (block.IsArmorClass())
                                activeArmorBlockList.Add(blockInfo);
                            else
                                activeInfantryBlockList.Add(blockInfo);
                        }
                    }

                    foreach (Block block in gameInfoProvider.GetRegionsAxisBlockList(battleRegion))
                    {
                        if (block.IsArmorClass())
                            nonActiveArmorBlockList.Add(block);
                        else
                            nonActiveInfantryBlockList.Add(block);
                    }

                    if (attackingGSUSelections != null)
                    {
                        Dictionary<MapInfo.CountryID, int> attackingGSUSelectionsCopy = new Dictionary<MapInfo.CountryID, int>(attackingGSUSelections);
                        foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAlliedGSUList(battleRegion))
                        {
                            if (attackingGSUSelectionsCopy.ContainsKey(GSU.CountryOwner))
                            {
                                if (!GSU.OutOfSupply && attackingGSUSelectionsCopy[GSU.CountryOwner] > 0)
                                {
                                    attackerGSUList.Add(GSU.Copy());
                                    attackingGSUSelectionsCopy[GSU.CountryOwner]--;
                                }
                            }
                        }
                    }

                    if (defendingGSUSelections != null)
                    {
                        Dictionary<MapInfo.CountryID, int> defendingGSUSelectionsCopy = new Dictionary<MapInfo.CountryID, int>(defendingGSUSelections);
                        foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAxisGSUList(battleRegion))
                        {
                            if (defendingGSUSelectionsCopy.ContainsKey(GSU.CountryOwner))
                            {
                                if (!GSU.OutOfSupply && defendingGSUSelectionsCopy[GSU.CountryOwner] > 0)
                                {
                                    defenderGSUList.Add(GSU.Copy());
                                    defendingGSUSelectionsCopy[GSU.CountryOwner]--;
                                }
                            }
                        }
                    }
                }
                else
                {
                    foreach (Block block in gameInfoProvider.GetRegionsAxisBlockList(battleRegion))
                    {
                        bool addBlock = false;
                        if (countriesSpendingSAInBattle != null && countriesSpendingSAInBattle.Count > 0)
                        {
                            if (countriesSpendingSAInBattle.Contains(block.CountryOwner) || (countriesSpendingSAInBattle.Contains(MapInfo.CountryID.USA) && block.CountryOwner == MapInfo.CountryID.FreeFrance) || (MapInfo.IsAxisMinorPower(block.CountryOwner) && countriesSpendingSAInBattle.Contains(MapInfo.CountryID.Germany)))
                                addBlock = true;
                        }
                        else
                            addBlock = true;
                        if (addBlock)
                        {
                            BlockInfo blockInfo = new BlockInfo(block);
                            if (block.IsArmorClass())
                                activeArmorBlockList.Add(blockInfo);
                            else
                                activeInfantryBlockList.Add(blockInfo);
                        }
                    }

                    foreach (Block block in gameInfoProvider.GetRegionsAlliedBlockList(battleRegion))
                    {
                        if (block.IsArmorClass())
                            nonActiveArmorBlockList.Add(block);
                        else
                            nonActiveInfantryBlockList.Add(block);
                    }

                    if (attackingGSUSelections != null)
                    {
                        Dictionary<MapInfo.CountryID, int> attackingGSUSelectionsCopy = new Dictionary<MapInfo.CountryID, int>(attackingGSUSelections);
                        foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAxisGSUList(battleRegion))
                        {
                            if (attackingGSUSelectionsCopy.ContainsKey(GSU.CountryOwner))
                            {
                                if (!GSU.OutOfSupply && attackingGSUSelectionsCopy[GSU.CountryOwner] > 0)
                                {
                                    attackerGSUList.Add(GSU.Copy());
                                    attackingGSUSelectionsCopy[GSU.CountryOwner]--;
                                }
                            }
                        }
                    }

                    if (defendingGSUSelections != null)
                    {
                        Dictionary<MapInfo.CountryID, int> defendingGSUSelectionsCopy = new Dictionary<MapInfo.CountryID, int>(defendingGSUSelections);
                        foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAlliedGSUList(battleRegion))
                        {
                            if (defendingGSUSelectionsCopy.ContainsKey(GSU.CountryOwner))
                            {
                                if (!GSU.OutOfSupply && defendingGSUSelectionsCopy[GSU.CountryOwner] > 0)
                                {
                                    defenderGSUList.Add(GSU.Copy());
                                    defendingGSUSelectionsCopy[GSU.CountryOwner]--;
                                }
                            }
                        }
                    }
                }

                this.attackingArmorListView.View = View.Tile;
                this.attackingArmorListView.TileSize = new Size((int)(PlayingPieceGraphics.GetBlockSize().Width * 1.2), (int)(PlayingPieceGraphics.GetBlockSize().Height * 1.2));
                foreach (BlockInfo blockInfo in activeArmorBlockList)
                {
                    this.attackingArmorListView.Items.Add(blockInfo.block.GetDescription());
                }

                this.attackingInfantryListView.View = View.Tile;
                this.attackingInfantryListView.TileSize = new Size((int)(PlayingPieceGraphics.GetBlockSize().Width * 1.2), (int)(PlayingPieceGraphics.GetBlockSize().Height * 1.2));
                foreach (BlockInfo blockInfo in activeInfantryBlockList)
                {
                    this.attackingInfantryListView.Items.Add(blockInfo.block.GetDescription());
                }

                this.defendingArmorListView.View = View.Tile;
                this.defendingArmorListView.TileSize = new Size((int)(PlayingPieceGraphics.GetBlockSize().Width * 1.2), (int)(PlayingPieceGraphics.GetBlockSize().Height * 1.2));
                foreach (Block block in nonActiveArmorBlockList)
                {
                    this.defendingArmorListView.Items.Add(block.GetDescription());
                }

                this.defendingInfantryListView.View = View.Tile;
                this.defendingInfantryListView.TileSize = new Size((int)(PlayingPieceGraphics.GetBlockSize().Width * 1.2), (int)(PlayingPieceGraphics.GetBlockSize().Height * 1.2));
                foreach (Block block in nonActiveInfantryBlockList)
                {
                    this.defendingInfantryListView.Items.Add(block.GetDescription());
                }
            }
            else
            {
                if (attacker == GameController.playerType.AlliedPlayer)
                {
                    foreach (Block block in gameInfoProvider.GetRegionsAxisBlockList(battleRegion))
                    {
                        BlockInfo blockInfo = new BlockInfo(block);
                        if (block.IsArmorClass())
                            activeArmorBlockList.Add(blockInfo);
                        else
                            activeInfantryBlockList.Add(blockInfo);
                    }

                    foreach (Block block in gameInfoProvider.GetRegionsAlliedBlockList(battleRegion))
                    {
                        bool addBlock = false;
                        if (countriesSpendingSAInBattle != null && countriesSpendingSAInBattle.Count > 0)
                        {
                            if (countriesSpendingSAInBattle.Contains(block.CountryOwner) || (countriesSpendingSAInBattle.Contains(MapInfo.CountryID.USA) && block.CountryOwner == MapInfo.CountryID.FreeFrance) || (MapInfo.IsAxisMinorPower(block.CountryOwner) && countriesSpendingSAInBattle.Contains(MapInfo.CountryID.Germany)))
                                addBlock = true;
                        }
                        else
                            addBlock = true;
                        if (addBlock)
                        {
                            if (block.IsArmorClass())
                                nonActiveArmorBlockList.Add(block);
                            else
                                nonActiveInfantryBlockList.Add(block);
                        }
                    }

                    if (attackingGSUSelections != null)
                    {
                        Dictionary<MapInfo.CountryID, int> attackingGSUSelectionsCopy = new Dictionary<MapInfo.CountryID, int>(attackingGSUSelections);
                        foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAlliedGSUList(battleRegion))
                        {
                            if (attackingGSUSelectionsCopy.ContainsKey(GSU.CountryOwner))
                            {
                                if (!GSU.OutOfSupply && attackingGSUSelectionsCopy[GSU.CountryOwner] > 0)
                                {
                                    attackerGSUList.Add(GSU.Copy());
                                    attackingGSUSelectionsCopy[GSU.CountryOwner]--;
                                }
                            }
                        }
                    }

                    if (defendingGSUSelections != null)
                    {
                        Dictionary<MapInfo.CountryID, int> defendingGSUSelectionsCopy = new Dictionary<MapInfo.CountryID, int>(defendingGSUSelections);
                        foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAxisGSUList(battleRegion))
                        {
                            if (defendingGSUSelectionsCopy.ContainsKey(GSU.CountryOwner))
                            {
                                if (!GSU.OutOfSupply && defendingGSUSelectionsCopy[GSU.CountryOwner] > 0)
                                {
                                    defenderGSUList.Add(GSU.Copy());
                                    defendingGSUSelectionsCopy[GSU.CountryOwner]--;
                                }
                            }
                        }
                    }
                }
                else
                {
                    foreach (Block block in gameInfoProvider.GetRegionsAlliedBlockList(battleRegion))
                    {
                        BlockInfo blockInfo = new BlockInfo(block);
                        if (block.IsArmorClass())
                            activeArmorBlockList.Add(blockInfo);
                        else
                            activeInfantryBlockList.Add(blockInfo);
                    }

                    foreach (Block block in gameInfoProvider.GetRegionsAxisBlockList(battleRegion))
                    {
                        bool addBlock = false;
                        if (countriesSpendingSAInBattle != null && countriesSpendingSAInBattle.Count > 0)
                        {
                            if (countriesSpendingSAInBattle.Contains(block.CountryOwner) || (countriesSpendingSAInBattle.Contains(MapInfo.CountryID.USA) && block.CountryOwner == MapInfo.CountryID.FreeFrance) || (MapInfo.IsAxisMinorPower(block.CountryOwner) && countriesSpendingSAInBattle.Contains(MapInfo.CountryID.Germany)))
                                addBlock = true;
                        }
                        else
                            addBlock = true;
                        if (addBlock)
                        {
                            if (block.IsArmorClass())
                                nonActiveArmorBlockList.Add(block);
                            else
                                nonActiveInfantryBlockList.Add(block);
                        }
                    }

                    if (attackingGSUSelections != null)
                    {
                        Dictionary<MapInfo.CountryID, int> attackingGSUSelectionsCopy = new Dictionary<MapInfo.CountryID, int>(attackingGSUSelections);
                        foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAxisGSUList(battleRegion))
                        {
                            if (attackingGSUSelectionsCopy.ContainsKey(GSU.CountryOwner))
                            {
                                if (!GSU.OutOfSupply && attackingGSUSelectionsCopy[GSU.CountryOwner] > 0)
                                {
                                    attackerGSUList.Add(GSU.Copy());
                                    attackingGSUSelectionsCopy[GSU.CountryOwner]--;
                                }
                            }
                        }
                    }

                    if (defendingGSUSelections != null)
                    {
                        Dictionary<MapInfo.CountryID, int> defendingGSUSelectionsCopy = new Dictionary<MapInfo.CountryID, int>(defendingGSUSelections);
                        foreach (GroundSupportUnit GSU in gameInfoProvider.GetRegionsAlliedGSUList(battleRegion))
                        {
                            if (defendingGSUSelectionsCopy.ContainsKey(GSU.CountryOwner))
                            {
                                if (!GSU.OutOfSupply && defendingGSUSelectionsCopy[GSU.CountryOwner] > 0)
                                {
                                    defenderGSUList.Add(GSU.Copy());
                                    defendingGSUSelectionsCopy[GSU.CountryOwner]--;
                                }
                            }
                        }
                    }
                }

                this.attackingArmorListView.View = View.Tile;
                this.attackingArmorListView.TileSize = new Size((int)(PlayingPieceGraphics.GetBlockSize().Width * 1.2), (int)(PlayingPieceGraphics.GetBlockSize().Height * 1.2));
                foreach (Block block in nonActiveArmorBlockList)
                {
                    this.attackingArmorListView.Items.Add(block.GetDescription());
                }

                this.attackingInfantryListView.View = View.Tile;
                this.attackingInfantryListView.TileSize = new Size((int)(PlayingPieceGraphics.GetBlockSize().Width * 1.2), (int)(PlayingPieceGraphics.GetBlockSize().Height * 1.2));
                foreach (Block block in nonActiveInfantryBlockList)
                {
                    this.attackingInfantryListView.Items.Add(block.GetDescription());
                }

                this.defendingArmorListView.View = View.Tile;
                this.defendingArmorListView.TileSize = new Size((int)(PlayingPieceGraphics.GetBlockSize().Width * 1.2), (int)(PlayingPieceGraphics.GetBlockSize().Height * 1.2));
                foreach (BlockInfo blockInfo in activeArmorBlockList)
                {
                    this.defendingArmorListView.Items.Add(blockInfo.block.GetDescription());
                }

                this.defendingInfantryListView.View = View.Tile;
                this.defendingInfantryListView.TileSize = new Size((int)(PlayingPieceGraphics.GetBlockSize().Width * 1.2), (int)(PlayingPieceGraphics.GetBlockSize().Height * 1.2));
                foreach (BlockInfo blockInfo in activeInfantryBlockList)
                {
                    this.defendingInfantryListView.Items.Add(blockInfo.block.GetDescription());
                }
            }

            this.attackerGSUListView.View = View.Tile;
            this.attackerGSUListView.TileSize = new Size(PlayingPieceGraphics.GetGSUSize().Width + PlayingPieceGraphics.GetGSUSize().Width / 3, PlayingPieceGraphics.GetGSUSize().Height + PlayingPieceGraphics.GetGSUSize().Height / 3);
            foreach (GroundSupportUnit attackingGSU in attackerGSUList)
            {
                this.attackerGSUListView.Items.Add(attackingGSU.GetDescription());
            }

            this.defenderGSUListView.View = View.Tile;
            this.defenderGSUListView.TileSize = new Size(PlayingPieceGraphics.GetGSUSize().Width + PlayingPieceGraphics.GetGSUSize().Width / 3, PlayingPieceGraphics.GetGSUSize().Height + PlayingPieceGraphics.GetGSUSize().Height / 3);
            foreach (GroundSupportUnit defendingGSU in defenderGSUList)
            {
                this.defenderGSUListView.Items.Add(defendingGSU.GetDescription());
            }

            this.battleIcons.SetBattleIcons(gameInfoProvider, battleRegion, false);
            AutomaticallyAssignRequiredLosses();
        }

        public Dictionary<PlayingPiece, int> GetAssignedLosses()
        {
            Dictionary<PlayingPiece, int> lossesToReturn = new Dictionary<PlayingPiece, int>();
            foreach (BlockInfo blockInfo in activeArmorBlockList)
            {
                if (blockInfo.numLosses > 0)
                    lossesToReturn.Add(blockInfo.block, blockInfo.numLosses);
            }

            foreach (BlockInfo blockInfo in activeInfantryBlockList)
            {
                if (blockInfo.numLosses > 0)
                    lossesToReturn.Add(blockInfo.block, blockInfo.numLosses);
            }

            return lossesToReturn;
        }

        private void ResetLossesLabels()
        {
            int numArmorLossesAssigned = 0;
            int numInfantryLossesAssigned = 0;

            foreach (BlockInfo blockInfo in activeArmorBlockList)
            {
                numArmorLossesAssigned += blockInfo.numLosses;
            }

            foreach (BlockInfo blockInfo in activeInfantryBlockList)
            {
                numInfantryLossesAssigned += blockInfo.numLosses;
            }

            if (shownForAttacker)
            {
                this.defenderInfantryHitsLabel.Visible = false;
                this.defenderInfantryHitsPictureBox.Visible = false;
                this.defenderInfantryOfLabel.Visible = false;
                this.defenderInfantryHitsAssignedLabel.Visible = false;
                this.defenderInfantryHitsAssignedPictureBox.Visible = false;
                this.defenderArmorHitsLabel.Visible = false;
                this.defenderArmorHitsPictureBox.Visible = false;
                this.defenderArmorOfLabel.Visible = false;
                this.defenderArmorHitsAssignedLabel.Visible = false;
                this.defenderArmorHitsAssignedPictureBox.Visible = false;
                this.defenderInfantryAssignedLabel.Visible = false;
                this.defenderArmorAssignedLabel.Visible = false;

                this.attakerInfantryHitslabel.Text = this.numInfantryHits.ToString();
                this.attackerInfantryHitsAssignedLabel.Text = numInfantryLossesAssigned.ToString();
                this.attakerArmorHitsLabel.Text = this.numArmorHits.ToString();
                this.attakerArmorHitsAssignedLabel.Text = numArmorLossesAssigned.ToString();
            }
            else
            {
                this.attakerInfantryHitslabel.Visible = false;
                this.attakerInfantryHitsPictureBox.Visible = false;
                this.attackerInfantryOfLabel.Visible = false;
                this.attackerInfantryHitsAssignedLabel.Visible = false;
                this.attackerInfantryHitsAssignedPictureBox.Visible = false;
                this.attakerArmorHitsLabel.Visible = false;
                this.attakerArmorHitsPictureBox.Visible = false;
                this.attackerArmorOfLabel.Visible = false;
                this.attakerArmorHitsAssignedLabel.Visible = false;
                this.attakerArmorHitsAssignedPictureBox.Visible = false;
                this.attackerArmorAssignedLabel.Visible = false;
                this.attackerInfantryAssignedLabel.Visible = false;

                this.defenderInfantryHitsLabel.Text = this.numInfantryHits.ToString();
                this.defenderInfantryHitsAssignedLabel.Text = numInfantryLossesAssigned.ToString();
                this.defenderArmorHitsLabel.Text = this.numArmorHits.ToString();
                this.defenderArmorHitsAssignedLabel.Text = numArmorLossesAssigned.ToString();
            }
        }

        private void AutomaticallyAssignRequiredLosses()
        {
            int numArmorSteps = 0;
            int numFullStrengthArmorBlocks = 0;
            int numInfantrySteps = 0;
            int numFullStrengthInfantryBlocks = 0;

            foreach (BlockInfo blockInfo in activeArmorBlockList)
            {
                numArmorSteps += (int)blockInfo.block.CurrentStrength;
                if (blockInfo.block.CurrentStrength == blockInfo.block.MaxStrength)
                    numFullStrengthArmorBlocks++;
            }

            foreach (BlockInfo blockInfo in activeInfantryBlockList)
            {
                numInfantrySteps += (int)blockInfo.block.CurrentStrength;
                if (blockInfo.block.CurrentStrength == blockInfo.block.MaxStrength)
                    numFullStrengthInfantryBlocks++;
            }

            if (numArmorSteps <= this.numArmorHits)
            {
                foreach (BlockInfo blockInfo in activeArmorBlockList)
                {
                    blockInfo.numLosses = (int)blockInfo.block.CurrentStrength;
                }
            }
            else if (numFullStrengthArmorBlocks <= this.numArmorHits)
            {
                foreach (BlockInfo blockInfo in activeArmorBlockList)
                {
                    if (blockInfo.block.CurrentStrength == blockInfo.block.MaxStrength)
                        blockInfo.numLosses = 1;
                }
            }

            if (numInfantrySteps <= this.numInfantryHits)
            {
                foreach (BlockInfo blockInfo in activeInfantryBlockList)
                {
                    blockInfo.numLosses = (int)blockInfo.block.CurrentStrength;
                }
            }
            else if (numFullStrengthInfantryBlocks <= this.numInfantryHits)
            {
                foreach (BlockInfo blockInfo in activeInfantryBlockList)
                {
                    if (blockInfo.block.CurrentStrength == blockInfo.block.MaxStrength)
                        blockInfo.numLosses = 1;
                }
            }

            ResetLossesLabels();
            this.Invalidate();
        }

        private void attackerGSUListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintGSU(e.Graphics, attackerGSUList[e.ItemIndex], new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), false);
        }

        private void defenderGSUListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            PlayingPieceGraphics.PaintGSU(e.Graphics, defenderGSUList[e.ItemIndex], new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), false);
        }

        private void attackingArmorListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            if (shownForAttacker)
            {
                if (activeArmorBlockList[e.ItemIndex].block.CurrentStrength > activeArmorBlockList[e.ItemIndex].numLosses)
                {
                    Block blockToDraw = activeArmorBlockList[e.ItemIndex].block.Copy();
                    blockToDraw.CurrentStrength -= (uint)activeArmorBlockList[e.ItemIndex].numLosses;
                    PlayingPieceGraphics.PaintBlock(e.Graphics, blockToDraw, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
                }
            }
            else
                PlayingPieceGraphics.PaintBlock(e.Graphics, nonActiveArmorBlockList[e.ItemIndex], new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
        }

        private void attackingInfantryListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            if (shownForAttacker)
            {
                if (activeInfantryBlockList[e.ItemIndex].block.CurrentStrength > activeInfantryBlockList[e.ItemIndex].numLosses)
                {
                    Block blockToDraw = activeInfantryBlockList[e.ItemIndex].block.Copy();
                    blockToDraw.CurrentStrength -= (uint)activeInfantryBlockList[e.ItemIndex].numLosses;
                    PlayingPieceGraphics.PaintBlock(e.Graphics, blockToDraw, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
                }
            }
            else
                PlayingPieceGraphics.PaintBlock(e.Graphics, nonActiveInfantryBlockList[e.ItemIndex], new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
        }

        private void defendingArmorListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            if (!shownForAttacker)
            {
                if (activeArmorBlockList[e.ItemIndex].block.CurrentStrength > activeArmorBlockList[e.ItemIndex].numLosses)
                {
                    Block blockToDraw = activeArmorBlockList[e.ItemIndex].block.Copy();
                    blockToDraw.CurrentStrength -= (uint)activeArmorBlockList[e.ItemIndex].numLosses;
                    PlayingPieceGraphics.PaintBlock(e.Graphics, blockToDraw, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
                }
            }
            else
                PlayingPieceGraphics.PaintBlock(e.Graphics, nonActiveArmorBlockList[e.ItemIndex], new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
        }

        private void defendingInfantryListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            if (!shownForAttacker)
            {
                if (activeInfantryBlockList[e.ItemIndex].block.CurrentStrength > activeInfantryBlockList[e.ItemIndex].numLosses)
                {
                    Block blockToDraw = activeInfantryBlockList[e.ItemIndex].block.Copy();
                    blockToDraw.CurrentStrength -= (uint)activeInfantryBlockList[e.ItemIndex].numLosses;
                    PlayingPieceGraphics.PaintBlock(e.Graphics, blockToDraw, new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
                }
            }
            else
                PlayingPieceGraphics.PaintBlock(e.Graphics, nonActiveInfantryBlockList[e.ItemIndex], new Point(e.Bounds.Left + (e.Bounds.Width / 2), e.Bounds.Top + (e.Bounds.Height / 2)), 1, false);
        }

        private bool CanAssignLoss(BlockInfo blockInfoToCheck, List<BlockInfo> listOfBlockInfoToCheck)
        {
            if (blockInfoToCheck.block.CurrentStrength == blockInfoToCheck.block.MaxStrength && blockInfoToCheck.numLosses == 0)
                return true;
            foreach (BlockInfo blockInfo in listOfBlockInfoToCheck)
            {
                if (blockInfo.block.CurrentStrength == blockInfo.block.MaxStrength && blockInfo.numLosses == 0)
                    return false;
            }

            return true;
        }

        private void AssignLoss(BlockInfo blockInfoToAssignLossTo)
        {
            blockInfoToAssignLossTo.numLosses++;
            ResetLossesLabels();
            this.Invalidate();
            if (shownForAttacker)
            {
                this.attackingInfantryListView.Invalidate();
                this.attackingArmorListView.Invalidate();
            }
            else
            {
                this.defendingInfantryListView.Invalidate();
                this.defendingArmorListView.Invalidate();
            }
        }

        private void attackingArmorListView_MouseClick(object sender, MouseEventArgs e)
        {
            if (shownForAttacker)
            {
                if (e.Button == MouseButtons.Right)
                {
                    if (this.activeArmorBlockList[attackingArmorListView.SelectedItems[0].Index].block.CurrentStrength > this.activeArmorBlockList[attackingArmorListView.SelectedItems[0].Index].numLosses)
                    {
                        if (Int32.Parse(this.attakerArmorHitsAssignedLabel.Text) < this.numArmorHits)
                        {
                            if (CanAssignLoss(this.activeArmorBlockList[attackingArmorListView.SelectedItems[0].Index], this.activeArmorBlockList))
                                AssignLoss(this.activeArmorBlockList[attackingArmorListView.SelectedItems[0].Index]);
                            else
                                MessageBox.Show(@"6.27...All full-strength units
within the targeted class must take one step-loss each before additional
losses may be allocated to other units");
                        }
                    }
                }
            }
        }

        private void attackingInfantryListView_MouseClick(object sender, MouseEventArgs e)
        {
            if (shownForAttacker)
            {
                if (e.Button == MouseButtons.Right)
                {
                    if (this.activeInfantryBlockList[attackingInfantryListView.SelectedItems[0].Index].block.CurrentStrength > this.activeInfantryBlockList[attackingInfantryListView.SelectedItems[0].Index].numLosses)
                    {
                        if (Int32.Parse(this.attackerInfantryHitsAssignedLabel.Text) < this.numInfantryHits)
                        {
                            if (CanAssignLoss(this.activeInfantryBlockList[attackingInfantryListView.SelectedItems[0].Index], this.activeInfantryBlockList))
                                AssignLoss(this.activeInfantryBlockList[attackingInfantryListView.SelectedItems[0].Index]);
                            else
                                MessageBox.Show(@"6.27...All full-strength units
within the targeted class must take one step-loss each before additional
losses may be allocated to other units");
                        }
                    }

                }
            }
        }

        private void defendingArmorListView_MouseClick(object sender, MouseEventArgs e)
        {
            if (!shownForAttacker)
            {
                if (e.Button == MouseButtons.Right)
                {
                    if (this.activeArmorBlockList[defendingArmorListView.SelectedItems[0].Index].block.CurrentStrength > this.activeArmorBlockList[defendingArmorListView.SelectedItems[0].Index].numLosses)
                    {
                        if (Int32.Parse(this.defenderArmorHitsAssignedLabel.Text) < this.numArmorHits)
                        {
                            if (CanAssignLoss(this.activeArmorBlockList[defendingArmorListView.SelectedItems[0].Index], this.activeArmorBlockList))
                                AssignLoss(this.activeArmorBlockList[defendingArmorListView.SelectedItems[0].Index]);
                            else
                                MessageBox.Show(@"6.27...All full-strength units
within the targeted class must take one step-loss each before additional
losses may be allocated to other units");
                        }
                    }
                }
            }
        }

        private void defendingInfantryListView_MouseClick(object sender, MouseEventArgs e)
        {
            if (!shownForAttacker)
            {
                if (e.Button == MouseButtons.Right)
                {
                    if (this.activeInfantryBlockList[defendingInfantryListView.SelectedItems[0].Index].block.CurrentStrength > this.activeInfantryBlockList[defendingInfantryListView.SelectedItems[0].Index].numLosses)
                    {
                        if (Int32.Parse(this.defenderInfantryHitsAssignedLabel.Text) < this.numInfantryHits)
                        {
                            if (CanAssignLoss(this.activeInfantryBlockList[defendingInfantryListView.SelectedItems[0].Index], this.activeInfantryBlockList))
                                AssignLoss(this.activeInfantryBlockList[defendingInfantryListView.SelectedItems[0].Index]);
                            else
                                MessageBox.Show(@"6.27...All full-strength units
within the targeted class must take one step-loss each before additional
losses may be allocated to other units");
                        }
                    }

                }
            }
        }

        private void DoOK()
        {
            if (shownForAttacker)
            {
                if (Int32.Parse(this.attakerArmorHitsAssignedLabel.Text) != this.numArmorHits)
                {
                    MessageBox.Show("You have only allocated " + this.defenderArmorHitsAssignedLabel.Text + " out of " + numArmorHits + " Armor hits");
                    return;
                }

                if (Int32.Parse(this.attackerInfantryHitsAssignedLabel.Text) != this.numInfantryHits)
                {
                    MessageBox.Show("You have only allocated " + this.attackerInfantryHitsAssignedLabel.Text + " out of " + numInfantryHits + " Infantry hits");
                    return;
                }
            }
            else
            {
                if (Int32.Parse(this.defenderArmorHitsAssignedLabel.Text) != this.numArmorHits)
                {
                    MessageBox.Show("You have only allocated " + this.attakerArmorHitsAssignedLabel.Text + " out of " + numArmorHits + " Armor hits");
                    return;
                }

                if (Int32.Parse(this.defenderInfantryHitsAssignedLabel.Text) != this.numInfantryHits)
                {
                    MessageBox.Show("You have only allocated " + this.defenderInfantryHitsAssignedLabel.Text + " out of " + numInfantryHits + " Infantry hits");
                    return;
                }
            }

            this.Close();
        }

        private void OkButton_Click(object sender, EventArgs e)
        {
            DoOK();
        }

        private void AssignCombatLossesDialog_Shown(object sender, EventArgs e)
        {
            this.battleIcons.SetBattleIconVisibility();
        }

        private void AssignCombatLossesDialog_KeyUp(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Space || e.KeyCode == Keys.Enter)
            {
                DoOK();
            }
        }
    }
}